<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    /* 
    产生闭包3个条件
      1. 函数嵌套
      2. 内部函数使用外部函数的局部变量
      3. 调用外部函数
    闭包:
      包含被引用变量的对象
      它被内部函数引入着
    产生闭包的时机:
      执行内部函数定义/产生内部函数对象
    使用闭包
      执行内部函数(通过外部引用来执行)
    释放闭包
      将指向内部函数的外部引用变量赋为null
    闭包的作用:
      延长了局部变量的生命周期
      能在外部反复使用到局部变量数据
    闭包的缺点:
      容易造成内存泄漏 => 及时让内部函数的外部引用赋为null
    */
    function fn1() {
      var a = 1
      // fn2是一个局部变量 => 引用类型的 => 指向内部函数对象
      const fn2 = function () {  // 产生闭包
        a++
        console.log(a)
      }
      return fn2
    }
    const f = fn1() // f => 内部函数对象
    f() // 2   // 使用闭包
    f() // 3   // 使用闭包
    f() // 4   // 使用闭包
    f = null // 释放闭包

    /* function fn2() { // fn2不是函数对象, 是指向函数对象的引用变量
      
    } */


    // (() => {
    //   let a = 2
    //   function fn() {
    //     console.log(a)
    //   }
    //   function fn2() {
    //     console.log(a++)
    //   }
    //   window.fn = fn
    // })()
    // fn()


    function showDelay(msg, time) {
      const timeoutId = setTimeout(() => {
        alert(msg)
      }, time);

      // clearTimeout(timeoutId)
    }
    showDelay('abc', 1000)
  </script>
</body>
</html>